<template>
  <div>
    <div id="map"></div>
  </div>
</template>

<script>
// 引入mapbox-gl
import mapboxgl from "mapbox-gl";
import "mapbox-gl/dist/mapbox-gl.css";

// 引入标绘工具
import MapboxDraw from "@mapbox/mapbox-gl-draw";
import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";

// 地图控件
import {
  RulerControl,
  StylesControl,
  CompassControl,
  ZoomControl,
  InspectControl,
  TooltipControl,
  LanguageControl,
  ImageControl,
} from "mapbox-gl-controls";

// 地理编码控件
import MapboxGeocoder from "@mapbox/mapbox-gl-geocoder";
import "@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css";

export default {
  name: "mapbox1",
  data() {
    return {
      map: null,
      draw: null,
    };
  },
  mounted() {
    this.initMap();

    this.addDraw();

    this.addScale();
    this.addGeocoder();

    this.addRulerControl();
    this.addStyleChangeControl();
    this.addCompassControl();
    this.addZoomControl();
    this.addLanguageControl();
    this.addInspectControl();
    // this.addTooltipControl();
  },
  methods: {
    // 初始化地图
    initMap() {
      mapboxgl.accessToken =
        "pk.eyJ1IjoieWFuZ3Rhby1tZCIsImEiOiJjbGZobXljYmU0Ymh3M3JudHoweWtsOWZzIn0.SkdYuelBPL1oa6ERn34UqQ";
      this.map = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11",
        center: [115, 35],
        zoom: 5,
      });
      this.map.addControl(new mapboxgl.FullscreenControl(), "bottom-right");
    },
    // 增加点线面绘制工具
    addDraw() {
      this.draw = new MapboxDraw();
      this.map.addControl(this.draw, "top-right");
      this.map.on("draw-create", this.updateArea);
      this.map.on("draw-delete", this.updateArea);
      this.map.on("draw-update", this.updateArea);
    },
    updateArea(e) {
      console.log(e);
      let data = this.draw.getAll();
      let answer = document.getElementById("calculated-area");
      if (data.features.length > 0) {
        let area = turf.area(data);
        let rounded_area = Math.round(area * 100) / 100;
        answer.innerHTML =
          "<p><strong>" + rounded_area + "</strong></p><p>square meters</p>";
      } else {
        answer.innerHTML = "";
        if (e.type !== "draw.delete")
          alert("Use the draw tools to draw a polygon!");
      }
    },
    // 增加长度测量控件
    addRulerControl() {
      this.map.addControl(new RulerControl(), "top-right");
      this.map.on("ruler.on", () => {
        console.log("ruler.on");
      });
      this.map.on("ruler.off", () => {
        console.log("ruler.off");
      });
    },
    // 增加地图风格切换控件
    addStyleChangeControl() {
      this.map.addControl(
        new StylesControl({
          styles: [
            {
              label: "Streets",
              styleName: "Mapbox Streets",
              styleUrl: "mapbox://styles/mapbox/streets-v9",
            },
            {
              label: "Satellite",
              styleName: "Satellite",
              styleUrl: "mapbox://styles/mapbox/satellite-v9",
            },
          ],
          onChange: (style) => console.log(style),
        }),
        "top-left"
      );
    },
    // 增加指北针控件
    addCompassControl() {
      this.map.addControl(new CompassControl(), "top-right");
    },
    // 增加地图缩放控件
    addZoomControl() {
      this.map.addControl(new ZoomControl(), "top-right");
    },
    // 增加不同语言标注控件
    addLanguageControl() {
      this.map.addControl(
        new LanguageControl({
          language: "chinese",
        })
      );
    },
    // InspectControl
    addInspectControl() {
      this.map.addControl(new InspectControl(), "bottom-right");
    },
    // 增加提示控件
    addTooltipControl() {
      this.map.addLayer({
        id: "$fill",
        type: "fill",
        source: { type: "geojson", data: polygon },
        paint: { "fill-opacity": 0.3, "fill-color": "#4264fb" },
      });
      this.map.addControl(
        new TooltipControl({
          layer: "$fill",
        })
      );
    },

    // 增加比例尺控件
    addScale() {
      const scale = new mapboxgl.ScaleControl({
        maxWidth: 80,
        unit: "metric",
      });
      this.map.addControl(scale);
    },

    // 增加地理编码控件
    addGeocoder() {
      const coordinatesGeocoder = function (query) {
        const matches = query.match(
          /^[ ]*(?:Lat: )?(-?\d+\.?\d*)[, ]+(?:Lng: )?(-?\d+\.?\d*)[ ]*$/i
        );
        if (!matches) {
          return null;
        }
        function coordinateFeature(lng, lat) {
          return {
            center: [lng, lat],
            geometry: {
              type: "Point",
              coordinates: [lng, lat],
            },
            place_name: "Lat: " + lat + " Lng: " + lng,
            place_type: ["coordinate"],
            properties: {},
            type: "Feature",
          };
        }

        const coord1 = Number(matches[1]);
        const coord2 = Number(matches[2]);
        const geocodes = [];

        if (coord1 < -90 || coord1 > 90) {
          // must be lng, lat
          geocodes.push(coordinateFeature(coord1, coord2));
        }

        if (coord2 < -90 || coord2 > 90) {
          // must be lat, lng
          geocodes.push(coordinateFeature(coord2, coord1));
        }

        if (geocodes.length === 0) {
          // else could be either lng, lat or lat, lng
          geocodes.push(coordinateFeature(coord1, coord2));
          geocodes.push(coordinateFeature(coord2, coord1));
        }

        return geocodes;
      };
      let geocode = new MapboxGeocoder({
        accessToken: mapboxgl.accessToken,
        localGeocoder: coordinatesGeocoder,
        zoom: 4,
        placeholder: "Try: -40, 170",
        mapboxgl: mapboxgl,
        reverseGeocode: true,
      });
      this.map.addControl(geocode, "top-left");
    },
  },
};
</script>

<style scoped>
#map {
  position: absolute;
  top: 100px;
  bottom: 0;
  width: 100%;
  height: 100%;
}
</style>

<style>
/* 去掉mapbox的logo和版权声明 */
.mapboxgl-ctrl-logo {
  display: none !important;
}
.mapboxgl-ctrl-attrib-inner {
  display: none !important;
}
</style>
